

------ clock divider-------

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
USE ieee.std_logic_arith.ALL;

entity c1hz is
	port(	clk 	: in std_logic;
			clkout 	: out std_logic;
			SWT  	: in std_logic);
end c1hz;

architecture behavior of c1hz is
	constant num : integer := 8;
	signal cnt : integer := 0;
	begin
		process(clk, SWT)
			begin
				if(clk'event and clk='1' and SWT = '1') then
					if(cnt > (num/2 - 1))then
						clkout <= '1';
						cnt <= cnt+1;
						if(cnt = num-1)then
							cnt <= 0;
						end if;
					else
						cnt <= cnt+1;
						clkout <='0';
					end if;
				END if;
		end process;
end behavior;


---------------dinclk---------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Dinclk is
	port(	CLOCK_50: in std_logic;
			SWT		: in std_logic;
			iyin 	: in std_logic_vector(7 downto 0);
			idin	: in std_logic_vector (11 downto 0);
			id		: out std_logic;
			idr		: out std_logic;
			clkout	: out std_logic);
END Dinclk;

ARCHITECTURE beh of Dinclk is

	TYPE STATETYPE IS (S0, S1, S2, S3, S4, S5, S6);
	SIGNAL currstate, nextstate: statetype;
	constant Dcon : std_logic_vector(11 downto 0) := "100111111110";
	constant Dcon2 : std_logic_vector(11 downto 0) := "000000000011";
	constant Ycon : std_logic_vector(7 downto 0) := "11101111";
begin
state: PROCESS (currstate, SWT, iyin, idin)
		BEGIN
			CASE currstate IS
				WHEN S0 =>
					If (SWT = '1') then

						clkout <= '0';
						
						id <= '0';
						idr <= '1';
						
						nextstate <= S5;
					Else
						clkout <= '0';
						
						id <= '0';
						idr <= '1';
						
						nextstate <= S0;
					End if;
					
				WHEN S1 =>
					
					clkout <= '0';
					
					id <= '1';
					idr <= '0';
					if (idin = Dcon2) then
						nextstate <= S3;
					else
						nextstate <= S2;
					End if;
					
					
				WHEN S2 =>
					
					clkout <= '0';
					
					id <= '1';
					idr <= '0';
					
					if (idin = Dcon2) then
						nextstate <= S3;
					else
						nextstate <= S1;
					End if;
				
				WHEN S3 =>
					
					clkout <= '1';
					
					id <= '1';
					idr <= '0';
					
					if (idin = Dcon + Dcon2) then
						nextstate <= S5;
					else
						nextstate <= S4;
					End if;
					
					
				WHEN S4 =>
					
					clkout <= '1';
					
					id <= '1';
					idr <= '0';
					
					if (idin = Dcon + Dcon2) then
						nextstate <= S5;
					else
						nextstate <= S4;
					End if; 
					
				WHEN S5 =>
						
					clkout <= '0';
					
					id <= '0';
					idr <= '1';
					
					If (iyin = Ycon)then
						nextstate <= S1;
					else
						nextstate <= S6;
					End if;
					
				WHEN S6 =>
						
					clkout <= '0';
					
					id <= '0';
					idr <= '1';
					
					If (iyin = Ycon)then
						nextstate <= S1;
					else
						nextstate <= S5;
					End if;
					
				END CASE;
		END PROCESS state;
		
		
		Statereg: PROCESS (CLOCK_50)
		BEGIN
			IF (CLOCK_50 = '1' and CLOCK_50'event) THEN
				IF (SWT = '0') THEN
					currstate <= S0;
				ELSE
					currstate <= nextstate;
				END IF;
			END IF;
		END PROCESS statereg;
		
end beh;
----------XYclk-------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity XYclk is
	 port(	clk 	: in std_logic;
			SWT  	: in std_logic;
			ixin 	: in std_logic_vector(7 downto 0);
			ix   	: out std_logic;
			ixr   	: out std_logic;
			iyin 	: in std_logic_vector(7 downto 0);
			iy   	: out std_logic;
			iyr   	: out std_logic;
			clkout	: out std_logic_vector (1 downto 0));
end XYclk;

architecture Behavioral of XYclk is

	TYPE STATETYPE IS (S0, S1, S2, S3, S4, S3c, S3b);
	SIGNAL currstate, nextstate: statetype;

	constant Ycon : std_logic_vector(7 downto 0) := "11101111";
	constant Xcon : std_logic_vector(7 downto 0) := "10011111";

	
begin
state: PROCESS (currstate, SWT, ixin, iyin)
		BEGIN
			CASE currstate IS
				WHEN S0 =>
					IF (SWT = '1') THEN
						clkout(1) <= '1';
						clkout(0) <= '1';
						
						iy <= '0';
						iyr <= '1';
						ix <= '0';
						ixr <= '1';

				
						nextstate <= S1;	
					ELSE
						clkout(1) <= '0';
						clkout(0) <= '0';
						
						iy <= '0';
						iyr <= '1';
						ix <= '0';
						ixr <= '1';
	
						
						nextstate <= S0;
					END IF;
					
				WHEN S1 =>
					clkout(1) <= '0';
					clkout(0) <= '0';
				
					iy <= '0';
					iyr <= '0';
					ix <= '0';
					ixr <= '0';

					if (ixin = Xcon) then
						if (iyin = Ycon) then
							nextstate <= S4;
						else
							nextstate <= S3;
						end if;	
					
					else
						nextstate <= S2;
					end if;

				WHEN S2 =>	
					
					clkout(1) <= '0';
					clkout(0) <= '1';	
									
					iy <= '0';
					iyr <= '0';
					ix <= '1';
					ixr <= '0';

					nextstate <= S1;
									
				WHEN S3 =>
					
					clkout(1) <= '1';
					clkout(0) <= '1';	
					
					iy <= '1';
					iyr <= '0';
					ix <= '0';
					ixr <= '1';

					nextstate <= S3b;
					
				WHEN S3b =>
					
					clkout(1) <= '1';
					clkout(0) <= '0';	
					
					iy <= '0';
					iyr <= '0';
					ix <= '0';
					ixr <= '0';

					nextstate <= S3c;
				
				WHEN S3c =>
					
					clkout(1) <= '0';
					clkout(0) <= '1';	
					
					iy <= '0';
					iyr <= '0';
					ix <= '1';
					ixr <= '0';

					nextstate <= S1;
					
				WHEN S4 =>
				
					clkout(1) <= '1';
					clkout(0) <= '1';	
					
					iy <= '0';
					iyr <= '1';
					ix <= '0';
					ixr <= '1';

					nextstate <= S1;					
				
			END CASE;
		END PROCESS state;
		
		
		Statereg: PROCESS (clk)
		BEGIN
			IF (clk = '1' and clk'event) THEN
				IF (SWT = '0') THEN
					currstate <= S0;
				ELSE
					currstate <= nextstate;
				END IF;
			END IF;
		END PROCESS statereg;
					
			
end Behavioral;





---------- Counter ----------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
USE ieee.std_logic_arith.ALL;

ENTITY My_Counter IS
	PORT(	clk 	: in std_logic;
			counter	: OUT std_logic_vector (7 downto 0);
			count 	: IN std_logic;
			reset	: IN std_logic);
END My_Counter;  

ARCHITECTURE behav OF My_Counter IS
	SIGNAL buff : std_logic_vector (7 downto 0) := "00000000";
BEGIN
	PROCESS(reset, count, clk) 
	BEGIN
		IF (clk = '1' and clk'event) THEN
			if (reset = '1') then
				buff <= "00000000";
			else
				if (count = '1') then
					buff <= buff + "00000001";
				end if;
			end if;	
		END if;	
   END PROCESS;
	counter <= buff;
END behav;

----------12bit Counter ----------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
USE ieee.std_logic_arith.ALL;

ENTITY My_Counter12 IS
	PORT(	clk 	: in std_logic;
			counter	: OUT std_logic_vector (11 downto 0);
			count 	: IN std_logic;
			reset	: IN std_logic);
END My_Counter12;  

ARCHITECTURE behav OF My_Counter12 IS
	SIGNAL buff : std_logic_vector (11 downto 0) := "000000000000";
BEGIN
	PROCESS(reset, count, clk) 
	BEGIN
		IF (clk = '1' and clk'event) THEN
			if (reset = '1') then
				buff <= "000000000000";
			else
				if (count = '1') then
					buff <= buff + "000000000001";
				end if;
			end if;	
		END if;	
   END PROCESS;
	counter <= buff;
END behav;

-----------3bit d flipflop------------------


library ieee ;
use ieee.std_logic_1164.all;
use work.all;

entity mydff is
	port(	clock   : in std_logic;
			data_in	: in std_logic_vector (2 downto 0);
			data_out: out std_logic_vector (2 downto 0));
end mydff;

architecture behv of mydff is
begin

    process(data_in, clock)
    begin

        -- clock rising edge

	if (clock='1' and clock'event) then
	    data_out <= data_in;
	end if;

    end process;	

end behv;


	
	

---------Top level--------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity toplevel is
	port(	CLOCK_50: in std_logic;
			SW   	: in STD_logic_vector (10 downto 0);
			--LEDG	: out STD_logic_vector (3 downto 0);
			LEDR	: out STD_logic_vector (9 downto 2);
			GPIO_1	: inout STD_logic_vector (35 downto 0));
			
end toplevel;

Architecture struct of toplevel is

component Dinclk is
	port(	CLOCK_50: in std_logic;
			SWT		: in std_logic;
			iyin 	: in std_logic_vector(7 downto 0);
			idin	: in std_logic_vector (11 downto 0);
			id		: out std_logic;
			idr		: out std_logic;
			clkout	: out std_logic);
END component;

component XYclk is
	port(	clk 	: in std_logic;
			SWT  	: in std_logic;
			ixin 	: in std_logic_vector(7 downto 0);
			ix   	: out std_logic;
			ixr   	: out std_logic;
			iyin 	: in std_logic_vector(7 downto 0);
			iy   	: out std_logic;
			iyr   	: out std_logic;
			clkout	: out std_logic_vector (1 downto 0));
end component;

component c1hz is
	port(	clk 	: in std_logic;
			clkout 	: out std_logic;
			SWT  	: in std_logic);
end component;

component My_Counter IS
	PORT(	clk 	: in std_logic;
			counter	: OUT std_logic_vector (7 downto 0);
			count 	: IN std_logic;
			reset	: IN std_logic);
END component;

component My_Counter12 IS
	PORT(	clk 	: in std_logic;
			counter	: OUT std_logic_vector (11 downto 0);
			count 	: IN std_logic;
			reset	: IN std_logic);
END component;

component mydff is
	port(	clock   : in std_logic;
			data_in	: in std_logic_vector (2 downto 0);
			data_out: out std_logic_vector (2 downto 0));
end component;

SIGNAL clk1, resetx, countx, resety, county, resetdin, countdin, Din_clk: std_logic;
SIGNAL xval, yval: std_logic_vector(7 downto 0);
SIGNAL dinval: std_logic_vector(11 downto 0);
SIGNAL XY_clk : std_logic_vector (1 downto 0);
SIGNAL XYD_in, XYD_out : std_logic_vector (2 downto 0);
begin
	clkdiv		: c1hz port map (CLOCK_50, clk1, SW(1));
	XY_1		: XYclk port map (clk1, SW(0), xval, countx, resetx, yval, county, resety, XY_clk);
	Din			: Dinclk port map (CLOCK_50, SW(0), yval, dinval, countdin, resetdin, Din_clk);
	xcount		: My_Counter port map (clk1, xval, countx, resetx);
	ycount		: My_Counter port map (clk1, yval, county, resety);
	dincount	: My_Counter12 port map (CLOCK_50, dinval, countdin, resetdin);
	gfilter		: mydff port map (CLOCK_50, XYD_in, XYD_out);
	
	XYD_in(1 downto 0) <= XY_clk;
	XYD_in(2) <= Din_clk;
	

--	filter		: mydff port map (CLOCK_50, myclk, filtered_clk);

	GPIO_1 (15)	<= XYD_out(0);
	GPIO_1 (19)	<= XYD_out(1);
	GPIO_1 (17)	<= XYD_out(2);
	GPIO_1 (13)	<= sw(10);
	GPIO_1 (21)	<= sw(2);
	GPIO_1 (23)	<= sw(3);
	GPIO_1 (25)	<= sw(4);
	GPIO_1 (27)	<= sw(5);
	GPIO_1 (29)	<= sw(6);
	GPIO_1 (31)	<= sw(7);
	GPIO_1 (33)	<= sw(8);
	GPIO_1 (35)	<= sw(9);
	
	LEDR(2)		<= sw(2);
	LEDR(3)		<= sw(3);
	LEDR(4)		<= sw(4);
	LEDR(5)		<= sw(5);
	LEDR(6)		<= sw(6);
	LEDR(7)		<= sw(7);
	LEDR(8)		<= sw(8);
	LEDR(9)		<= sw(9);
End struct;
